# a lot of projecting mapping uses repetitive computations that can 
# stored in arrays rather than recomputed on the fly.  Here these
# computations are stored.

import numpy

class CoordinateLookup:
	def __init__(self,N,shiftx,shifty):
		self.N = N
		self.shiftx = shiftx
		self.shifty = shifty

	def get_xindices(self):
		A = numpy.zeros((self.N,2),numpy.int32)
		for i in range(self.N):
			crdx = int(i+self.shiftx)
			A[i,0] = int(numpy.floor(i+self.shiftx))
			A[i,1] = int(numpy.floor(i+self.shiftx)) + 1
		return A.clip(0,self.N-1)

	def get_yindices(self):
		A = numpy.zeros((self.N,2),numpy.int32)
		for i in range(self.N):
			A[i,0] = int(numpy.floor(i+self.shifty))
			A[i,1] = int(numpy.floor(i+self.shifty)) + 1
		return A.clip(0,self.N-1)

	def get_weights(self):
		w00 = (1.0 - self.shiftx)*(1.0 - self.shifty)
		w01 = (1.0 - self.shiftx)*self.shifty
		w10 = self.shiftx*(1.0 - self.shifty)
		w11 = self.shiftx*self.shifty

		A = numpy.zeros((self.N,self.N,2,2),numpy.float32)
		for i in range(self.N):
			for j in range(self.N):
				A[i,j,0,0] = w00
				A[i,j,0,1] = w01
				A[i,j,1,0] = w10
				A[i,j,1,1] = w11

				if i + self.shiftx < 0: A[i,j,0,:] = 0.0
				if i + self.shiftx + 1 < 0: A[i,j,1,:] = 0.0

				if i + self.shiftx > N-1: A[i,j,0,:] = 0.0
				if i + self.shiftx + 1 > N-1: A[i,j,1,:] = 0.0

				if j + self.shifty < 0: A[i,j,:,0] = 0.0
				if j + self.shifty + 1 < 0: A[i,j,:,1] = 0.0

				if j + self.shifty > N-1: A[i,j,:,0] = 0.0
				if j + self.shifty + 1 > N-1: A[i,j,:,1] = 0.0

